'''
Created on Dec 5, 2010

@author: mkiyer

Main script to process a single sequence data set and 
prepare it for variant calling
'''
import sys
import os
import logging
#import argparse

from optparse import OptionParser
from base import JOB_SUCCESS, JOB_ERROR, up_to_date
from config import ExomePipelineConfig, ExomeLaneConfig
from job_runner import qsub_cac, qsub_loc, run_local
from copy_uncompress_seqdata import copy_sequence_job 
from bwa_align import bwa_job
from base_quality_conversion import illu2sanger

# define base paths to job scripts
_module_dir = os.path.abspath(os.path.dirname(__file__))

def run_job(lane_file, lane_root_dir, config_file, num_processors, runfunc):
    logging.info("Lane %s starting.." % (lane_file))    
    job = ExomeLaneConfig()
    job.from_xml(lane_file, lane_root_dir)
    config = ExomePipelineConfig()
    config.from_xml(config_file)
    deps = []
    # make output directory
    logging.info("%s: Output directory %s" % (job.name, job.output_dir))
    if not os.path.exists(job.output_dir):
        os.makedirs(job.output_dir)
        logging.info("%s: Created output directory %s" % (job.name, job.output_dir))
    #
    # Setup job by copying sequences
    #
    
    logging.info("%s: Copying sequences to output dir %s" % (job.name, job.output_dir))    
    retcode = copy_sequence_job(lane_file, lane_root_dir)
    if retcode != 0:
        logging.error("%s: Error setting up job" % (job.name))    
        return JOB_ERROR
    '''
    #
    # Uncompress sequences
    #
    if all(up_to_date(job.fastq_files[mate], joconfig_fileb.src_fastq_files[mate]) for mate in xrange(len(job.fastq_files))):
        logging.info("[SKIPPED] Uncompressed sequence files %s are up to date" % (job.fastq_files))
    else:
        logging.info("%s: Uncompressing sequences" % (job.name))
        py_script = os.path.join(_module_dir, "copy_uncompress_seqdata.py")
        args = [sys.executable, py_script, "--uncompress", lane_file, lane_root_dir]
        logging.debug("%s: Uncompress args=%s" % (job.name, args))
        job_id = runfunc(job.name, args, 1, cwd=job.output_dir, walltime="10:00:00", stdout="uncompress.log", 
                         email_addresses=None)
        deps = [job_id]
    '''
    #
    # Run FastQC
    #
    bwa_deps=[]
    qual_deps=[]
    if all(up_to_date(job.fastqc_html_files[mate], job.fastq_files[mate]) for mate in xrange(len(job.fastq_files))):
        logging.info("[SKIPPED] FastQC files are up to date" % (job.fastq_files))
    else:
        py_script = os.path.join(_module_dir, "fastqc.py")
        job_ids = []
        
        for mate in xrange(len(job.fastq_files)):
            args = [sys.executable, py_script, "--mate", str(mate), lane_file, lane_root_dir, config_file]        
            logging.info("%s: Running FastQC for quality assessment" % (job.name))
            print job.output_dir
            job_id = runfunc(job.name, args, 1, cwd=job.output_dir, walltime="24:00:00", 
                             stdout="fastqc_mate%d.log" % (mate), 
                             deps=deps, email_addresses=None)
            job_ids.append(job_id)
        #deps = job_ids
        
        # Convert the quality of the sequences from illumina to sanger
        # Check if the files are there.
            report_file=os.path.join(job.output_dir,'qualconv_mate%d.done'%(mate))
            print report_file
            logging.info("Report files %s" % (report_file))
            if os.path.exists(report_file):
                logging.info("[SKIPPED] Converting base quality for files are already sanger %s" % (job.fastq_files))
                logging.info("[SKIPPED] Previous Report files %s" % (report_file))
            elif job.quality_scores == "illumina":
                # ifile=lane name
                # ifile_fq = new lane name
                py_script2 = os.path.join(_module_dir, "base_quality_conversion.py")
                logging.info("Fastfq files %s" % (job.fastq_files[mate]))
                logging.info("Fastfq files %s" % (job.fastq_files[mate].replace('.fq', '.sfq')))
                
                args = [sys.executable, py_script2, "--ifile", job.fastq_files[mate], "--ifile_fq",job.fastq_files[mate].replace('.fq', '.sfq'),
					"--platform",job.quality_scores,"--report_file",report_file]
                logging.info("%s: Converting the Quality scale from illumina to Sanger of %s" % (job.name,job.fastq_files[mate]))
                qual_id = runfunc(job.name, args, 1, cwd=job.output_dir, walltime="24:00:00", 
							 stdout="qualconv_mate%d.log" % (mate), deps=deps, email_addresses=None)
                qual_deps.append(qual_id)
            
    #
    # Align with BWA
    #
    #deps=None # to remove
    #bwa_deps = []
    if all(up_to_date(job.align_bam_file, job.fastq_files[mate]) for mate in xrange(len(job.fastq_files))):
        logging.info("[SKIPPED] BWA Alignment BAM file(s) %s up to date" % (job.align_bam_file))
    else:
        logging.info("%s: Running BWA Alignment" % (job.name))
        #job_id = bwa_job(lane_file, config_file, num_processors, runfunc, deps=deps)
        job_id = bwa_job(lane_file, lane_root_dir, config_file, num_processors, runfunc, deps=qual_deps)
        bwa_deps = [job_id]
        
    print bwa_deps
    #
    # Make alignment report
    #
    return bwa_deps

def main():
    logging.basicConfig(level=logging.DEBUG,
                        format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    """
    NOTE 12-27-2010: parser was changed by optionparser because the first is not a 
    standard package of python. 
    parser = argparse.ArgumentParser()
    parser.add_argument("--local", dest="local", action="store_true", default=False)
    parser.add_argument("--cluster", dest="cluster", action="store_true", default=False)
    parser.add_argument("-p", "--processes", type=int, dest="num_processors", default=1)
    parser.add_argument("-o", "--output-dir", dest="output_dir")
    parser.add_argument("lane_file")
    parser.add_argument("config_file")
    options = parser.parse_args()
    """
        
    optionparser = OptionParser("usage: %prog [options] ")
    optionparser.add_option("--local", dest="local", action="store_true", default=False)
    optionparser.add_option("--cluster", dest="cluster", action="store_true", default=False)
    optionparser.add_option("-p", "--processes", type=int, dest="num_processors", default=1)
    optionparser.add_option("-o", "--output-dir", dest="output_dir")
    #optionparser.add_option("lane_file")    
    #optionparser.add_option("config_file")
    
    (options, args) = optionparser.parse_args()
    
    lane_file, config_file = args[0], args[1]
    
    if not (options.local ^ options.cluster):
        optionparser.error("Must set either --local or --cluster to run job")
    if options.local:
        jobrunfunc = run_local
    elif options.cluster:
        jobrunfunc = qsub
    #run_job(options.lane_file, options.config_file, options.output_dir, options.num_processors, jobrunfunc)
    run_job(lane_file, config_file, options.output_dir, options.num_processors, jobrunfunc)
    
if __name__ == '__main__': main()